package com.example.nick.bodyapplication.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View

class AlarmAreaView : View {

    // 20 * 15 ， 横向20，纵向15， (列20，行15)
    var column = 20
    var row = 15
    var itemWidth = 0.0f
    var itemHeight = 0.0f
    var paintLine = Paint(Paint.ANTI_ALIAS_FLAG)
    var paintRect = Paint(Paint.ANTI_ALIAS_FLAG)
    val strokeWidth = 2.0f
    val alarmArrays = Array(size = column * row, init = { 1 })
    var curRow = 0
    var curColumn = 0
    var modelOn = true

    constructor(ctx: Context) : super(ctx, null)
    constructor(ctx: Context, attrs: AttributeSet) : this(ctx, attrs, 0)
    constructor(ctx: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
        ctx,
        attrs,
        defStyleAttr
    ) {
        initAttrs(ctx, attrs)
    }

    private fun initAttrs(ctx: Context, attrs: AttributeSet) {
        //
        paintLine.color = Color.WHITE
        paintLine.strokeWidth = strokeWidth
    }

    override fun onDraw(canvas: Canvas) {
        itemWidth = (width / column).toFloat()
        itemHeight = (height / row).toFloat()
        canvas.save()
        drawRect(canvas)
        drawRowLine(canvas)
        drawColumnLine(canvas)
        canvas.restore()
    }

    private fun drawRowLine(canvas: Canvas) {
        for (i in 1 until row) {
            var y = i * itemHeight
            canvas.drawLine(0.0f, y, itemWidth * column, y, paintLine)
        }
    }

    private fun drawColumnLine(canvas: Canvas) {
        for (i in 1 until column) {
            var x = i * itemWidth
            canvas.drawLine(x, 0.0f, x, itemHeight * row, paintLine)
        }
    }

    private fun drawRect(canvas: Canvas) {
        alarmArrays.forEachIndexed { index, i ->
            val r = index / column
            val c = index % column
            paintRect.color = if (i == 1) Color.RED else Color.BLUE
            val left = c * itemWidth
            val top = r * itemHeight
            val right = (c + 1) * itemWidth
            val bottom = (r + 1) * itemHeight
//            if (r == 0 || c == 0) {
//                Log.i("area", "area r:$r, c:$c, left:$left, top:$top, right:$right, bottom:$bottom, itemWidth:$itemWidth, itemHeight:$itemHeight")
//            }
            canvas.drawRect(left, top, right, bottom, paintRect)
        }
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                val (r, c) = getRowColumn(event.x, event.y)
                if (r == -1 || c == -1) {
                    return true
                }
                curRow = r
                curColumn = c
                if (alarmArrays[r * column + c] == 1) {
                    alarmArrays[r * column + c] = 0
                    modelOn = false
                } else {
                    alarmArrays[r * column + c] = 1
                    modelOn = true
                }
                Log.i(
                    "area",
                    "area down x:${event.x}, y:${event.y}, r:$r, c:$c, modelOn:$modelOn"
                )
                invalidate()
            }
            MotionEvent.ACTION_MOVE -> {
                val (r, c) = getRowColumn(event.x, event.y)
                if (r == -1 || c == -1) {
                    return true
                }
                if (curRow != r || curColumn != c) {
                    dealTouchMove(r, c)
                    invalidate()
                }
            }
            MotionEvent.ACTION_UP -> {

            }
        }
        return true
    }

    fun dealTouchMove(moveR: Int, moveC: Int) {
        var beginRow = 0
        var beginColumn = 0
        var endRow = 0
        var endColumn = 0
        if (moveR > curRow) {
            beginRow = curRow
            endRow = moveR
        } else {
            beginRow = moveR
            endRow = curRow
        }

        if (moveC > curColumn) {
            beginColumn = curColumn
            endColumn = moveC
        } else {
            beginColumn = moveC
            endColumn = curColumn
        }

        for (index in 0..alarmArrays.size) {
            val r = index / column
            val c = index % column
            if (r in beginRow..endRow && c in beginColumn..endColumn) {
                alarmArrays[index] = if (modelOn) 1 else 0
            }
        }
        invalidate()
    }

    fun getRowColumn(touchX: Float, touchY: Float): Pair<Int, Int> {
//        var firR = touchY / itemHeight
//        var firC = touchX / itemWidth
//        val firRFlag = firR.toInt() + 0.5f
//        val firCFlag = firC.toInt() + 0.5f
//        if (Math.abs(firRFlag - firR) > 0.4 || Math.abs(firCFlag - firC) > 0.45) {
//            Log.e(
//                "area",
//                "area error touchY:$touchY, touchX:$touchX, itemHeight:$itemHeight, itemWidth:$itemWidth, height:$height, width:$width"
//            )
//            Log.e(
//                "area",
//                "area error firR:$firR, firC:$firC, firRFlag:$firRFlag, firCFlag:$firCFlag"
//            )
//            return Pair(-1, -1)
//        }

        var r = (touchY / itemHeight).toInt()
        var c = (touchX / itemWidth).toInt()

        if (r >= row || c >= column) {
            Log.e(
                "area",
                "area error r:$r, c:$c, touchY:$touchY, touchX:$touchX, itemHeight:$itemHeight, itemWidth:$itemWidth, height:$height, width:$width"
            )
        }

        if (r >= row) {
            r = row - 1
        }

        if (c >= column) {
            c = column - 1
        }

        return Pair(r, c)
    }

}